﻿using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Xml;
using DiagramDesigner.BusinessModelObject;
using DiagramDesigner.Utils;
using DiagramDesigner.Controls;
using System.Reflection;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AvalonDock;
using System.Collections.Generic;

namespace DiagramDesigner
{
    public partial class DesignerCanvas : Canvas
    {
        private Point? rubberbandSelectionStartPoint = null;

        private SelectionService selectionService;
        internal SelectionService SelectionService
        {
            get
            {
                if (selectionService == null)
                    selectionService = new SelectionService(this);

                return selectionService;
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Source == this)
            {
                // in case that this click is the start of a 
                // drag operation we cache the start point
                this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));

                // if you click directly on the canvas all 
                // selected items are 'de-selected'
                SelectionService.ClearSelection();
                Focus();
                e.Handled = true;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // if mouse button is not pressed we have no drag operation, ...
            if (e.LeftButton != MouseButtonState.Pressed)
                this.rubberbandSelectionStartPoint = null;

            // ... but if mouse button is pressed and start
            // point value is set we do have one
            if (this.rubberbandSelectionStartPoint.HasValue)
            {
                // create rubberband adorner
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
                if (adornerLayer != null)
                {
                    RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
                    if (adorner != null)
                    {
                        adornerLayer.Add(adorner);
                    }
                }
            }
            e.Handled = true;
        }

        public static void contextMenuSpatial(ref DesignerItem newItem)
        {
            ContextMenu mainMenu = new ContextMenu();
            newItem.ContextMenu = mainMenu;

            Uri myUriCopy = new Uri("Resources/Images/Copy.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage copyimage = new BitmapImage();
            copyimage.BeginInit();
            copyimage.UriSource = myUriCopy;
            copyimage.EndInit();
            //
            Image iconImageCopy = new Image();
            iconImageCopy.Source = copyimage;
            iconImageCopy.Width = 16;

            Uri myUriCut = new Uri("Resources/Images/Cut.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage cutimage = new BitmapImage();
            cutimage.BeginInit();
            cutimage.UriSource = myUriCut;
            cutimage.EndInit();
            //
            Image iconImageCut = new Image();
            iconImageCut.Source = cutimage;
            iconImageCut.Width = 16;

            Uri myUriPaste = new Uri("Resources/Images/Paste.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage pasteimage = new BitmapImage();
            pasteimage.BeginInit();
            pasteimage.UriSource = myUriPaste;
            pasteimage.EndInit();
            //
            Image iconImagePaste = new Image();
            iconImagePaste.Source = pasteimage;
            iconImagePaste.Width = 16;


            Uri myUriDelete = new Uri("Resources/Images/Delete.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage deleteimage = new BitmapImage();
            deleteimage.BeginInit();
            deleteimage.UriSource = myUriDelete;
            deleteimage.EndInit();
            //
            Image iconImageDelete = new Image();
            iconImageDelete.Source = deleteimage;
            iconImageDelete.Width = 16;

            ///////////////////
            Uri myUriPoint = new Uri("Resources/Images/Point.png", UriKind.RelativeOrAbsolute);
            BitmapImage imagePoint = new BitmapImage();
            imagePoint.BeginInit();
            imagePoint.UriSource = myUriPoint;
            imagePoint.EndInit();
            Image iconImagePoint = new Image();
            iconImagePoint.Source = imagePoint;
            iconImagePoint.Width = 16;

            Uri myUriLine = new Uri("Resources/Images/Line.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageLine = new BitmapImage();
            imageLine.BeginInit();
            imageLine.UriSource = myUriLine;
            imageLine.EndInit();
            Image iconImageLine = new Image();
            iconImageLine.Source = imageLine;
            iconImageLine.Width = 16;

            Uri myUriSurface = new Uri("Resources/Images/Surface.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageSurface = new BitmapImage();
            imageSurface.BeginInit();
            imageSurface.UriSource = myUriSurface;
            imageSurface.EndInit();
            Image iconImageSurface = new Image();
            iconImageSurface.Source = imageSurface;
            iconImageSurface.Width = 16;


            Uri myUriPointSet = new Uri("Resources/Images/PointSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imagePointSet = new BitmapImage();
            imagePointSet.BeginInit();
            imagePointSet.UriSource = myUriPointSet;
            imagePointSet.EndInit();
            Image iconImagePointSet = new Image();
            iconImagePointSet.Source = imagePointSet;
            iconImagePointSet.Width = 16;

            Uri myUriLineSet = new Uri("Resources/Images/LineSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageLineSet = new BitmapImage();
            imageLineSet.BeginInit();
            imageLineSet.UriSource = myUriLineSet;
            imageLineSet.EndInit();
            Image iconImageLineSet = new Image();
            iconImageLineSet.Source = imageLineSet;
            iconImageLineSet.Width = 16;

            Uri myUriSurfaceSet = new Uri("Resources/Images/SurfaceSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageSurfaceSet = new BitmapImage();
            imageSurfaceSet.BeginInit();
            imageSurfaceSet.UriSource = myUriSurfaceSet;
            imageSurfaceSet.EndInit();
            Image iconImageSurfaceSet = new Image();
            iconImageSurfaceSet.Source = imageSurfaceSet;
            iconImageSurfaceSet.Width = 16;


            MenuItem item1 = new MenuItem();
            item1.Header = "Cut";
            item1.Icon = iconImageCut;
            item1.Command = ApplicationCommands.Cut;
            item1.Foreground = Brushes.Black;
            item1.Background = Brushes.Transparent;
            mainMenu.Items.Add(item1);

            MenuItem item3 = new MenuItem();
            item3.Header = "Copy";
            item3.Icon = iconImageCopy;
            item3.Command = ApplicationCommands.Copy;
            mainMenu.Items.Add(item3);

            MenuItem item2 = new MenuItem();
            item2.Header = "Paste";
            item2.Icon = iconImagePaste;
            item2.Command = ApplicationCommands.Paste;
            mainMenu.Items.Add(item2);

            MenuItem item4 = new MenuItem();
            item4.Header = "Delete";
            item4.Icon = iconImageDelete;
            item4.Command = ApplicationCommands.Delete;
            mainMenu.Items.Add(item4);

            Separator sep = new Separator();
            mainMenu.Items.Add(sep);

            MenuItem item5 = new MenuItem();
            item5.Header = "Add non spatial measure";
            item5.Command = DesignerCanvas.NoSpatialMeasure;
            mainMenu.Items.Add(item5);

            MenuItem item6 = new MenuItem();
            item6.Header = "Add spatial measure";
            mainMenu.Items.Add(item6);

            MenuItem item61 = new MenuItem();
            item61.Header = "Add point measure";
            item61.Icon = iconImagePoint;
            item61.Command = DesignerCanvas.PointMeasure;
            item6.Items.Add(item61);

            MenuItem item62 = new MenuItem();
            item62.Header = "Add line measure";
            item62.Icon = iconImageLine;
            item62.Command = DesignerCanvas.LineMeasure;
            item6.Items.Add(item62);

            MenuItem item63 = new MenuItem();
            item63.Header = "Add surface measure";
            item63.Icon = iconImageSurface;
            item63.Command = DesignerCanvas.SurfaceMeasure;
            item6.Items.Add(item63);

            MenuItem item64 = new MenuItem();
            item64.Header = "Add point set measure";
            item64.Icon = iconImagePointSet;
            item64.Command = DesignerCanvas.PointSetMeasure;
            item6.Items.Add(item64);

            MenuItem item65 = new MenuItem();
            item65.Header = "Add line set measure";
            item65.Icon = iconImageLineSet;
            item65.Command = DesignerCanvas.LineSetMeasure;
            item6.Items.Add(item65);

            MenuItem item66 = new MenuItem();
            item66.Header = "Add surface set measure";
            item66.Icon = iconImageSurfaceSet;
            item66.Command = DesignerCanvas.SurfaceSetMeasure;
            item6.Items.Add(item66);
        }
        public static void contextMenuTemporal(ref DesignerItem newItem)
        {
            ContextMenu mainMenu = new ContextMenu();
            newItem.ContextMenu = mainMenu;

            Uri myUriCopy = new Uri("Resources/Images/Copy.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage copyimage = new BitmapImage();
            copyimage.BeginInit();
            copyimage.UriSource = myUriCopy;
            copyimage.EndInit();
            //
            Image iconImageCopy = new Image();
            iconImageCopy.Source = copyimage;
            iconImageCopy.Width = 16;

            Uri myUriCut = new Uri("Resources/Images/Cut.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage cutimage = new BitmapImage();
            cutimage.BeginInit();
            cutimage.UriSource = myUriCut;
            cutimage.EndInit();
            //
            Image iconImageCut = new Image();
            iconImageCut.Source = cutimage;
            iconImageCut.Width = 16;

            Uri myUriPaste = new Uri("Resources/Images/Paste.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage pasteimage = new BitmapImage();
            pasteimage.BeginInit();
            pasteimage.UriSource = myUriPaste;
            pasteimage.EndInit();
            //
            Image iconImagePaste = new Image();
            iconImagePaste.Source = pasteimage;
            iconImagePaste.Width = 16;


            Uri myUriDelete = new Uri("Resources/Images/Delete.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage deleteimage = new BitmapImage();
            deleteimage.BeginInit();
            deleteimage.UriSource = myUriDelete;
            deleteimage.EndInit();
            //
            Image iconImageDelete = new Image();
            iconImageDelete.Source = deleteimage;
            iconImageDelete.Width = 16;

            ///////////////////
            Uri myUriPoint = new Uri("Resources/Images/Point.png", UriKind.RelativeOrAbsolute);
            BitmapImage imagePoint = new BitmapImage();
            imagePoint.BeginInit();
            imagePoint.UriSource = myUriPoint;
            imagePoint.EndInit();
            Image iconImagePoint = new Image();
            iconImagePoint.Source = imagePoint;
            iconImagePoint.Width = 16;

            Uri myUriLine = new Uri("Resources/Images/Line.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageLine = new BitmapImage();
            imageLine.BeginInit();
            imageLine.UriSource = myUriLine;
            imageLine.EndInit();
            Image iconImageLine = new Image();
            iconImageLine.Source = imageLine;
            iconImageLine.Width = 16;

            Uri myUriSurface = new Uri("Resources/Images/Surface.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageSurface = new BitmapImage();
            imageSurface.BeginInit();
            imageSurface.UriSource = myUriSurface;
            imageSurface.EndInit();
            Image iconImageSurface = new Image();
            iconImageSurface.Source = imageSurface;
            iconImageSurface.Width = 16;


            Uri myUriPointSet = new Uri("Resources/Images/PointSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imagePointSet = new BitmapImage();
            imagePointSet.BeginInit();
            imagePointSet.UriSource = myUriPointSet;
            imagePointSet.EndInit();
            Image iconImagePointSet = new Image();
            iconImagePointSet.Source = imagePointSet;
            iconImagePointSet.Width = 16;

            Uri myUriLineSet = new Uri("Resources/Images/LineSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageLineSet = new BitmapImage();
            imageLineSet.BeginInit();
            imageLineSet.UriSource = myUriLineSet;
            imageLineSet.EndInit();
            Image iconImageLineSet = new Image();
            iconImageLineSet.Source = imageLineSet;
            iconImageLineSet.Width = 16;

            Uri myUriSurfaceSet = new Uri("Resources/Images/SurfaceSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageSurfaceSet = new BitmapImage();
            imageSurfaceSet.BeginInit();
            imageSurfaceSet.UriSource = myUriSurfaceSet;
            imageSurfaceSet.EndInit();
            Image iconImageSurfaceSet = new Image();
            iconImageSurfaceSet.Source = imageSurfaceSet;
            iconImageSurfaceSet.Width = 16;

            Uri myUriTimePoint = new Uri("Resources/Images/TimePoint.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimePoint = new BitmapImage();
            imageTimePoint.BeginInit();
            imageTimePoint.UriSource = myUriTimePoint;
            imageTimePoint.EndInit();
            Image iconImageTimePoint = new Image();
            iconImageTimePoint.Source = imageTimePoint;
            iconImageTimePoint.Width = 16;

            Uri myUriTimeLine = new Uri("Resources/Images/TimeLine.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimeLine = new BitmapImage();
            imageTimeLine.BeginInit();
            imageTimeLine.UriSource = myUriTimeLine;
            imageTimeLine.EndInit();
            Image iconImageTimeLine = new Image();
            iconImageTimeLine.Source = imageTimeLine;
            iconImageTimeLine.Width = 16;

            Uri myUriTimeSurface = new Uri("Resources/Images/TimeSurface.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimeSurface = new BitmapImage();
            imageTimeSurface.BeginInit();
            imageTimeSurface.UriSource = myUriTimeSurface;
            imageTimeSurface.EndInit();
            Image iconImageTimeSurface = new Image();
            iconImageTimeSurface.Source = imageTimeSurface;
            iconImageTimeSurface.Width = 16;

            Uri myUriTimePointSet = new Uri("Resources/Images/TimePointSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimePointSet = new BitmapImage();
            imageTimePointSet.BeginInit();
            imageTimePointSet.UriSource = myUriTimePointSet;
            imageTimePointSet.EndInit();
            Image iconImageTimePointSet = new Image();
            iconImageTimePointSet.Source = imageTimePointSet;
            iconImageTimePointSet.Width = 16;

            Uri myUriTimeLineSet = new Uri("Resources/Images/TimeLineSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimeLineSet = new BitmapImage();
            imageTimeLineSet.BeginInit();
            imageTimeLineSet.UriSource = myUriTimeLineSet;
            imageTimeLineSet.EndInit();
            Image iconImageTimeLineSet = new Image();
            iconImageTimeLineSet.Source = imageTimeLineSet;
            iconImageTimeLineSet.Width = 16;

            Uri myUriTimeSurfaceSet = new Uri("Resources/Images/TimeSurfaceSet.png", UriKind.RelativeOrAbsolute);
            BitmapImage imageTimeSurfaceSet = new BitmapImage();
            imageTimeSurfaceSet.BeginInit();
            imageTimeSurfaceSet.UriSource = myUriTimeSurfaceSet;
            imageTimeSurfaceSet.EndInit();
            Image iconImageTimeSurfaceSet = new Image();
            iconImageTimeSurfaceSet.Source = imageTimeSurfaceSet;
            iconImageTimeSurfaceSet.Width = 16;

            MenuItem item1 = new MenuItem();
            item1.Header = "Cut";
            item1.Icon = iconImageCut;
            item1.Command = ApplicationCommands.Cut;
            item1.Foreground = Brushes.Black;
            item1.Background = Brushes.Transparent;
            mainMenu.Items.Add(item1);

            MenuItem item3 = new MenuItem();
            item3.Header = "Copy";
            item3.Icon = iconImageCopy;
            item3.Command = ApplicationCommands.Copy;
            mainMenu.Items.Add(item3);

            MenuItem item2 = new MenuItem();
            item2.Header = "Paste";
            item2.Icon = iconImagePaste;
            item2.Command = ApplicationCommands.Paste;
            mainMenu.Items.Add(item2);

            MenuItem item4 = new MenuItem();
            item4.Header = "Delete";
            item4.Icon = iconImageDelete;
            item4.Command = ApplicationCommands.Delete;
            mainMenu.Items.Add(item4);

            Separator sep = new Separator();
            mainMenu.Items.Add(sep);

            MenuItem item5 = new MenuItem();
            item5.Header = "Add non temporal attribute";
            mainMenu.Items.Add(item5);

            MenuItem item51 = new MenuItem();
            item51.Header = "Add point attribute";
            item51.Icon = iconImagePoint;
            item51.Command = DesignerCanvas.PointAtribute;
            item5.Items.Add(item51);

            MenuItem item52 = new MenuItem();
            item52.Header = "Add line attribute";
            item52.Icon = iconImageLine;
            item52.Command = DesignerCanvas.LineAtribute;
            item5.Items.Add(item52);

            MenuItem item53 = new MenuItem();
            item53.Header = "Add surface attribute";
            item53.Icon = iconImageSurface;
            item53.Command = DesignerCanvas.SurfaceAtribute;
            item5.Items.Add(item53);

            MenuItem item54 = new MenuItem();
            item54.Header = "Add point set attribute";
            item54.Icon = iconImagePointSet;
            item54.Command = DesignerCanvas.PointSetAtribute;
            item5.Items.Add(item54);

            MenuItem item55 = new MenuItem();
            item55.Header = "Add line set attribute";
            item55.Icon = iconImageLineSet;
            item55.Command = DesignerCanvas.LineSetAtribute;
            item5.Items.Add(item55);

            MenuItem item56 = new MenuItem();
            item56.Header = "Add surface set attribute";
            item56.Icon = iconImageSurfaceSet;
            item56.Command = DesignerCanvas.SurfaceSetAtribute;
            item5.Items.Add(item56);

            MenuItem item57 = new MenuItem();
            item57.Header = "Add non spatial attribute";
            item57.Command = DesignerCanvas.NonSpatialAtribute;
            item5.Items.Add(item57);

            MenuItem item6 = new MenuItem();
            item6.Header = "Add temporal attribute";
            mainMenu.Items.Add(item6);

            MenuItem item61 = new MenuItem();
            item61.Header = "Add temp. point att.";
            item61.Icon = iconImageTimePoint;
            item61.Command = DesignerCanvas.TempPointAtribute;
            item6.Items.Add(item61);

            MenuItem item62 = new MenuItem();
            item62.Header = "Add temp. line att.";
            item62.Icon = iconImageTimeLine;
            item62.Command = DesignerCanvas.TempLineAtribute;
            item6.Items.Add(item62);

            MenuItem item63 = new MenuItem();
            item63.Header = "Add temp. surface att.";
            item63.Icon = iconImageTimeSurface;
            item63.Command = DesignerCanvas.TempSurfaceAtribute;
            item6.Items.Add(item63);

            MenuItem item64 = new MenuItem();
            item64.Header = "Add temp. point set att.";
            item64.Icon = iconImageTimePointSet;
            item64.Command = DesignerCanvas.TempPointSetAtribute;
            item6.Items.Add(item64);

            MenuItem item65 = new MenuItem();
            item65.Header = "Add temp. line set att.";
            item65.Icon = iconImageTimeLineSet;
            item65.Command = DesignerCanvas.TempLineSetAtribute;
            item6.Items.Add(item65);

            MenuItem item66 = new MenuItem();
            item66.Header = "Add temp. surface set att.";
            item66.Icon = iconImageTimeSurfaceSet;
            item66.Command = DesignerCanvas.TempSurfaceSetAtribute;
            item6.Items.Add(item66);

            MenuItem item67 = new MenuItem();
            item67.Header = "Add temp. non spatial att.";
            item67.Command = DesignerCanvas.TempNonSpatialAtribute;
            item6.Items.Add(item67);
        }
        public static void contextMenuCriterion(ref DesignerItem newItem)
        {
            ContextMenu mainMenu = new ContextMenu();
            newItem.ContextMenu = mainMenu;

            Uri myUriCopy = new Uri("Resources/Images/Copy.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage copyimage = new BitmapImage();
            copyimage.BeginInit();
            copyimage.UriSource = myUriCopy;
            copyimage.EndInit();
            //
            Image iconImageCopy = new Image();
            iconImageCopy.Source = copyimage;
            iconImageCopy.Width = 16;

            Uri myUriCut = new Uri("Resources/Images/Cut.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage cutimage = new BitmapImage();
            cutimage.BeginInit();
            cutimage.UriSource = myUriCut;
            cutimage.EndInit();
            //
            Image iconImageCut = new Image();
            iconImageCut.Source = cutimage;
            iconImageCut.Width = 16;

            Uri myUriPaste = new Uri("Resources/Images/Paste.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage pasteimage = new BitmapImage();
            pasteimage.BeginInit();
            pasteimage.UriSource = myUriPaste;
            pasteimage.EndInit();
            //
            Image iconImagePaste = new Image();
            iconImagePaste.Source = pasteimage;
            iconImagePaste.Width = 16;


            Uri myUriDelete = new Uri("Resources/Images/Delete.png", UriKind.RelativeOrAbsolute);
            //create image at runtime and attach to menu at runtime
            BitmapImage deleteimage = new BitmapImage();
            deleteimage.BeginInit();
            deleteimage.UriSource = myUriDelete;
            deleteimage.EndInit();
            //
            Image iconImageDelete = new Image();
            iconImageDelete.Source = deleteimage;
            iconImageDelete.Width = 16;

            MenuItem item1 = new MenuItem();
            item1.Header = "Cut";
            item1.Icon = iconImageCut;
            item1.Command = ApplicationCommands.Cut;
            item1.Foreground = Brushes.Black;
            item1.Background = Brushes.Transparent;
            mainMenu.Items.Add(item1);

            MenuItem item3 = new MenuItem();
            item3.Header = "Copy";
            item3.Icon = iconImageCopy;
            item3.Command = ApplicationCommands.Copy;
            mainMenu.Items.Add(item3);

            MenuItem item2 = new MenuItem();
            item2.Header = "Paste";
            item2.Icon = iconImagePaste;
            item2.Command = ApplicationCommands.Paste;
            mainMenu.Items.Add(item2);

            MenuItem item4 = new MenuItem();
            item4.Header = "Delete";
            item4.Icon = iconImageDelete;
            item4.Command = ApplicationCommands.Delete;
            mainMenu.Items.Add(item4);


        }

        protected override void OnDrop(DragEventArgs e)
        {
            base.OnDrop(e);
            int tamX = 0;
            int tamY = 0;
            DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
            if (dragObject != null && !String.IsNullOrEmpty(dragObject.Xaml))
            {
                DesignerItem newItem;
                Object content = XamlReader.Load(XmlReader.Create(new StringReader(dragObject.Xaml)));
                GUIFactTable objFactTable = new GUIFactTable();

                var grid = content as Grid;
                string nameObject = string.Empty;

                if (content != null && grid != null)
                {
                    newItem = new DesignerItem();

                    var image = grid.Children[0] as Image;
                    if (image != null)
                        switch (image.Tag.ToString())
                        {
                            case "FactRelationShipModel":
                                tamX = 170;
                                tamY = 150;
                                newItem.Content = objFactTable; //new GUIFactTable();
                                newItem.Tipo = "FactRelationShipModel";
                                contextMenuSpatial(ref newItem);
                                nameObject = "FactTable";
                                break;
                            case "LevelModel":
                                tamX = 170;
                                tamY = 150;
                                newItem.Content = new GUILevel();
                                newItem.Tipo = "LevelModel";
                                contextMenuTemporal(ref newItem);
                                nameObject = "Level";
                                break;
                            case "LSLevelModel":
                                tamX = 170;
                                tamY = 150;
                                newItem.Content = new GUILSLevel();
                                newItem.Tipo = "LSLevelModel";
                                contextMenuTemporal(ref newItem);
                                nameObject = "LSLevel";
                                break;
                            case "CriterionModel":
                                tamX = 100;
                                tamY = 30;
                                newItem.Content = new GUICriterion();
                                newItem.Tipo = "CriterionModel";
                                contextMenuCriterion(ref newItem);
                                nameObject = "Criterion";
                                break;
                            default:
                                tamX = 30;
                                tamY = 30;
                                newItem.Content = content;
                                break;
                        }


                    newItem.Item = GetBaseModelFromXamlReader(content);

                    if (newItem.Item is LinkModel)
                    {
                        #region Links
                        var askConnection = new AskConnection
                        {
                            ShowInTaskbar = false,
                            Canvas = this
                        };
                        var img = ((Grid)newItem.Content).Children[0] as Image;
                        if (img != null)
                        {
                            askConnection.Item = newItem.Item;
                            askConnection.LinkImage.Source = img.Source;
                            askConnection.LinkClass = (LinkModel)newItem.Item;
                        }

                        var dialogResult = askConnection.ShowDialog();
                        if (!(dialogResult.HasValue && dialogResult.Value)) return;
                        #endregion
                    }
                    else
                    {
                        #region Element
                        var f = Children.OfType<DesignerItem>().Where(m => m.Item.GetType() == newItem.Item.GetType());

                        if (nameObject != string.Empty)
                            ((MainElementModel)newItem.Item).Name = nameObject + (f.Count() + 1);
                        else
                            ((MainElementModel)newItem.Item).Name = newItem.Item.GetType().Name + (f.Count() + 1);

                        ShowProperties(newItem);

                        var position = e.GetPosition(this);

                        if (dragObject.DesiredSize.HasValue)
                        {
                            newItem.Width = tamX;
                            newItem.Height = tamY;

                            SetLeft(newItem, Math.Max(0, position.X - newItem.Width / 2));
                            SetTop(newItem, Math.Max(0, position.Y - newItem.Height / 2));
                        }
                        else
                        {
                            SetLeft(newItem, Math.Max(0, position.X));
                            SetTop(newItem, Math.Max(0, position.Y));
                        }

                        SetZIndex(newItem, Children.Count);
                        Children.Add(newItem);
                        SetConnectorDecoratorTemplate(newItem);

                        #region Acoplar Criterion al Nivel usando un Conector de Longitud 0
                        if (image.Tag.ToString().Equals("CriterionModel"))
                        {
                            var askConnectionCriterion = new AskConnectionCriterion
                            {
                                ShowInTaskbar = false,
                                Canvas = this,
                                Source = newItem.Name
                            };
                            // Indicar un conector
                            //askConnectionCriterion.Source = newItem.Name;
                            var dialogResult = askConnectionCriterion.ShowDialog();
                            if (!(dialogResult.HasValue && dialogResult.Value))
                            {
                                Children.Remove(newItem);
                                return;
                            }
                            else
                            {
                                newItem.NameItemRelation = askConnectionCriterion.Destination;

                                string leftPositionDestination;
                                string topPositionDestination;                                
                                DesignerItem newItemDestination;
                                newItemDestination = new DesignerItem();
                                newItemDestination = GetDesignerItem(this, askConnectionCriterion.Destination);                                
                                newItemDestination.Criterio = ((GUICriterion)newItem.Content).lblName.Content.ToString();
                                if(newItemDestination.Item is MainElementModel && newItem.Item is CriterionModel)
                                {
                                    ((CriterionModel)newItem.Item).DestinationItem = (MainElementModel)(newItemDestination.Item);
                                    ((MainElementModel) (newItemDestination.Item)).Criterion =
                                        (CriterionModel) newItem.Item;
                                }
                                ((GUICriterion)newItem.Content).Criterio = askConnectionCriterion.Destination;
                                leftPositionDestination = newItemDestination.GetValue(LeftProperty).ToString();
                                topPositionDestination = newItemDestination.GetValue(TopProperty).ToString();

                                //SetLeft(newItem, Math.Max(0, Convert.ToDouble(leftPositionDestination) + (newItemDestination.ActualWidth - newItem.ActualWidth)/2));
                                SetLeft(newItem, Canvas.GetLeft(newItemDestination));
                                SetTop(newItem, Math.Max(0, Convert.ToDouble(topPositionDestination) - tamY + 3));
                                newItem.Width = newItemDestination.Width;
                                
                                this.SelectionService.SelectItem(newItemDestination);
                                this.SelectionService.AddToSelection(newItem);

                                this.Group_Executed(null, null);                                
                            }
                        }
                        #endregion

                        //update selection
                        if (!image.Tag.ToString().Equals("CriterionModel"))
                        {
                            SelectionService.SelectItem(newItem);
                            newItem.Focus();
                        }
                        #endregion
                    }
                    var guiElement = newItem.Content as GUIElement;
                    if (guiElement != null) guiElement.DesigItem = newItem;
                }

                e.Handled = true;
            }
        }

        DesignerItem GetDesignerItem(DesignerCanvas dc,string name)
        {
            //var ie = Canvas.Children.OfType<DesignerItem>().Where(m => ((MainElementModel)m.Item).Name == name);
            var ie = dc.Children.OfType<DesignerItem>().Where(m => ((MainElementModel)m.Item).Name == name);
            var ge = ie.GetEnumerator();
            ge.MoveNext();
            var di = ge.Current;
            return di;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            Size size = new Size();

            foreach (UIElement element in this.InternalChildren)
            {
                double left = Canvas.GetLeft(element);
                double top = Canvas.GetTop(element);
                left = double.IsNaN(left) ? 0 : left;
                top = double.IsNaN(top) ? 0 : top;

                //measure desired size for each child
                element.Measure(constraint);

                Size desiredSize = element.DesiredSize;
                if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
                {
                    size.Width = Math.Max(size.Width, left + desiredSize.Width);
                    size.Height = Math.Max(size.Height, top + desiredSize.Height);
                }
            }
            // add margin 
            size.Width += 10;
            size.Height += 10;
            return size;
        }

        private void SetConnectorDecoratorTemplate(DesignerItem item)
        {
            if (item.ApplyTemplate() && item.Content is UIElement)
            {
                ControlTemplate template = DesignerItem.GetConnectorDecoratorTemplate(item.Content as UIElement);
                Control decorator = item.Template.FindName("PART_ConnectorDecorator", item) as Control;
                if (decorator != null && template != null)
                    decorator.Template = template;
            }
        }
    }
}
